import { listTopics } from "@autoscholar/core"; import { papers, paperTopics, paperVersions, series } from "@autoscholar/db"; import type { PublicPaperSummary } from "@autoscholar/schemas"; import { and, desc, eq, inArray } from "drizzle-orm"; import type { Metadata } from "next"; import Link from "next/link"; import { notFound } from "next/navigation"; import { Disclosure } from "@/components/Disclosure"; import { EmptyState } from "@/components/EmptyState"; import { PaperCard } from "@/components/PaperCard"; import { db } from "@/lib/server/db"; export const dynamic = "force-dynamic"; export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }): Promise { const { slug } = await params; const t = (await listTopics(db())).find((x) => x.slug === slug); return { title: t ? `${t.name} — topic` : "Topic", alternates: { canonical: `/topics/${slug}` } }; } export default async function TopicPage({ params }: { params: Promise<{ slug: string }> }) { const { slug } = await params; const d = db(); const topics = await listTopics(d); const topic = topics.find((x) => x.slug === slug); if (!topic) notFound(); const children = topics.filter((c) => c.parentId === topic.id); const parent = topics.find((c) => c.id === topic.parentId); const ids = [topic.id, ...children.map((c) => c.id)]; const staging = process.env.STAGING_MODE === "1"; const rows = await d .selectDistinctOn([papers.id], { p: papers, v: paperVersions, s: { slug: series.slug } }) .from(paperTopics) .innerJoin(papers, eq(paperTopics.paperId, papers.id)) .innerJoin(paperVersions, eq(papers.currentVersionId, paperVersions.id)) .leftJoin(series, eq(papers.seriesId, series.id)) .where(and(inArray(paperTopics.topicId, ids), staging ? undefined : eq(papers.synthetic, false))) .orderBy(papers.id, desc(papers.firstPublishedAt)); const items: PublicPaperSummary[] = rows .map((r) => ({ publicId: r.p.publicId, slug: r.p.slug, title: r.v.title, abstract: r.v.abstract, keywords: r.v.keywords, discipline: r.p.discipline, researchMode: r.p.researchMode, status: r.p.status as PublicPaperSummary["status"], versionNo: r.v.versionNo, firstPublishedAt: r.p.firstPublishedAt.toISOString(), updatedAt: r.p.updatedAt.toISOString(), seriesSlug: r.s?.slug ?? null, topics: [], hasCode: r.v.artifactSet.some((a) => a.kind === "code"), hasData: r.v.artifactSet.some((a) => a.kind === "data" && !/README|manifest/.test(a.path)), hasLatex: r.v.artifactSet.some((a) => a.path.endsWith(".tex")), synthetic: r.p.synthetic, })) .sort((a, b) => b.firstPublishedAt.localeCompare(a.firstPublishedAt)); return (

Topics {parent && ( <> {" "} / {parent.name} )}

{topic.name}

{topic.description &&

{topic.description}

} {children.length > 0 && (
    {children.map((c) => (
  • {c.name}
  • ))}
)}
{items.length === 0 ? ( Papers appear here once they pass every quality gate. ) : ( )}
); }